#include "AnimationManager.h"
#include "../../TinyXML/tinyxml.h"
#include "../../SGD_Wrappers/CSGD_TextureManager.h"
#include "../../SGD_Wrappers/SGD_String.h"
#include <string>

CAnimationManager*	CAnimationManager::GetInstance( void )
{
	//Store an instance in global memory
	static CAnimationManager s_Instance;

	//Return the instance
	return &s_Instance;
}

CAnimationManager::CAnimationManager(void)
{
}

CAnimationManager::~CAnimationManager(void)
{
}

void CAnimationManager::ClearMemory(void)
{
	auto startIndex = m_hmAnimations.begin();
	while(startIndex!=m_hmAnimations.end())
	{
		delete startIndex->second;
		startIndex++;
	}
	m_hmAnimations.clear();
}

int LoadTextureID(std::string sFileNameNode)
{
	sFileNameNode = "resource/animations/" + sFileNameNode;
	wchar_t* tsFileNameNode = new wchar_t[200];
	CSTR_TO_TSTR( tsFileNameNode, 200,sFileNameNode.c_str());
	int textureID = CSGD_TextureManager::GetInstance()->LoadTexture(tsFileNameNode,0UL);
	delete [] tsFileNameNode;
	return textureID ;
}

void CAnimationManager::LoadAnimationsXML(void)
{
	TiXmlDocument myDoc;
	myDoc.LoadFile("XML_UTF_8.xml");
	TiXmlElement* pNode = myDoc.RootElement();

	pNode = pNode->FirstChildElement("Files");
	
	TiXmlElement* pFileNode = pNode->FirstChildElement("File");
	while(pFileNode)
	{
		//Pre Load Animation
		LoadTextureID(pFileNode->Attribute("FileName"));
		pFileNode = pFileNode->NextSiblingElement("File");
	}
	pNode = pNode->NextSiblingElement("Animations");
	TiXmlElement* pAnimationNode = pNode->FirstChildElement("Animation");
	while(pAnimationNode)
	{
		std::string sName;
		int isLooping = 0;

		sName = pAnimationNode->Attribute("Name");
		pAnimationNode->Attribute("isLooping",&isLooping);
		
		CAnimation * pAnimation = new CAnimation;
		pAnimation->m_bIsLooping = (isLooping==1?true:false);
		pAnimation->m_sName = (sName);

		TiXmlElement* pFrameNode = pAnimationNode -> FirstChildElement("Frames");
		pFrameNode = pFrameNode -> FirstChildElement("Frame");

		while(pFrameNode)
		{
			CFrame * pFrame = new CFrame;

			std::string FrameFileName;
			double FrameDuration;
			std::string FrameTrigger;

			FrameFileName = pFrameNode->Attribute("FileName");
			pFrameNode->Attribute("FrameDuration",&FrameDuration);
			FrameTrigger = pFrameNode->Attribute("FrameTrigger");

			pFrame->m_fFrameDuration = (float)FrameDuration;
			pFrame->m_nTextureID = LoadTextureID(FrameFileName);
			pFrame->m_sEventTrigger = FrameTrigger;

			{
				TiXmlElement* pAnchorPoint = pFrameNode -> FirstChildElement("AnchorPoint");

				int anchorPointX;
				int anchorPointY;

				pAnchorPoint->Attribute("x",&anchorPointX);
				pAnchorPoint->Attribute("y",&anchorPointY);
				
				pFrame->AnchorX = (float)anchorPointX;
				pFrame->AnchorY = (float)anchorPointY;

			}
			
			{
				TiXmlElement*pRenderRect = pFrameNode -> FirstChildElement("RenderRect");
				int renderRectX;
				int renderRectY;
				int renderRectWidth;
				int renderRectHeight;

				pRenderRect->Attribute("x",&renderRectX);
				pRenderRect->Attribute("y",&renderRectY);
				pRenderRect->Attribute("width",&renderRectWidth);
				pRenderRect->Attribute("height",&renderRectHeight);
				
				pFrame->m_rSourceRect.left = renderRectX;
				pFrame->m_rSourceRect.top = renderRectY;
				pFrame->m_rSourceRect.right = renderRectX + renderRectWidth;
				pFrame->m_rSourceRect.bottom = renderRectY + renderRectHeight;
			}

			{
				TiXmlElement*pActiveCollisionRect = pFrameNode -> FirstChildElement("ActiveCollisionRect");
				int ActiveCollisionRectX;
				int ActiveCollisionRectY;
				int ActiveCollisionRectWidth;
				int ActiveCollisionRectHeight;

				pActiveCollisionRect->Attribute("x",&ActiveCollisionRectX);
				pActiveCollisionRect->Attribute("y",&ActiveCollisionRectY);
				pActiveCollisionRect->Attribute("width",&ActiveCollisionRectWidth);
				pActiveCollisionRect->Attribute("height",&ActiveCollisionRectHeight);

				pFrame->m_rActiveRect.left = ActiveCollisionRectX;
				pFrame->m_rActiveRect.top = ActiveCollisionRectY;
				pFrame->m_rActiveRect.right = ActiveCollisionRectX + ActiveCollisionRectWidth;
				pFrame->m_rActiveRect.bottom = ActiveCollisionRectY + ActiveCollisionRectHeight;
			}

			{
				TiXmlElement*pPassiveCollisionRect = pFrameNode -> FirstChildElement("PassiveCollisionRect");
				int PassiveCollisionRectX;
				int PassiveCollisionRectY;
				int PassiveCollisionRectWidth;
				int PassiveCollisionRectHeight;
				pPassiveCollisionRect->Attribute("x",&PassiveCollisionRectX);
				pPassiveCollisionRect->Attribute("y",&PassiveCollisionRectY);
				pPassiveCollisionRect->Attribute("width",&PassiveCollisionRectWidth);
				pPassiveCollisionRect->Attribute("height",&PassiveCollisionRectHeight);

				pFrame->m_rPassiveRect.left = PassiveCollisionRectX;
				pFrame->m_rPassiveRect.top = PassiveCollisionRectY;
				pFrame->m_rPassiveRect.right = PassiveCollisionRectX + PassiveCollisionRectWidth;
				pFrame->m_rPassiveRect.bottom = PassiveCollisionRectY + PassiveCollisionRectHeight;
			}
			pAnimation->m_vFrame.push_back(pFrame);

			pFrameNode = pFrameNode -> NextSiblingElement("Frame");
		}

		m_hmAnimations.insert(std::pair<std::string,CAnimation*>(pAnimation->m_sName,pAnimation));

		pAnimationNode = pAnimationNode->NextSiblingElement("Animation");
	}
}

CAnimation* CAnimationManager::GetAnimation(std::string name)
{
	return m_hmAnimations[name];
}
